import unittest

from just_pipeline.pipeline import Pipeline, pipeline, pipe, pipe_last
from operator import add


class TestPipelineModule(unittest.TestCase):
    def test_pipline_only_value(self):
        self.assertIsNone(pipeline()())
        self.assertEqual(1, pipeline(1)())
        self.assertEqual("abc", pipeline("abc")())

    def test_pipe(self):
        self.assertEqual(3, pipe(add, 1)(2))
        self.assertEqual("ab", pipe(add, "b")("a"))

    def test_pipline_with_pipe(self):
        got = pipeline("a")(
            pipe(add, "b"),
            pipe(add, "c"),
        )
        self.assertEqual("abc", got)

        got = pipeline(3)(
            pipe(add, 2),
            pipe(add, -5),
        )
        self.assertEqual(0, got)

    def test_pipline_list(self):
        got = Pipeline("a")[
            pipe(add, "b"),
            pipe(add, "c"),
        ].run()
        self.assertEqual("abc", got)

        got = Pipeline(3)[
            pipe(add, 2),
            pipe(add, -5),
        ].run()
        self.assertEqual(0, got)

    def test_pipline_with_pipe_last(self):
        def object_call(obj, attr: str, *args, **kwargs):
            """调用`obj`的指定成员函数"""
            return getattr(obj, attr)(*args, **kwargs)

        got = pipeline("a=1,b=2,bad,d='ok'")(
            pipe(object_call, "split", ","),
            pipe_last(map, lambda x: x.split("=")),
            pipe_last(filter, lambda x: len(x) == 2),
        )
        self.assertEqual({"a": "1", "b": "2", "d": "'ok'"}, dict(got))
